package com.youlu.campus.service.data.impl;

import com.alibaba.fastjson.JSON;
import com.mongodb.client.result.UpdateResult;
import com.youlu.campus.base.exception.BusinessException;

import com.youlu.campus.common.utils.TimeUtils;
import com.youlu.campus.entity.ActivitySimulationData;
import com.youlu.campus.entity.VO.req.ActivityDataQueryVO;
import com.youlu.campus.entity.data.DayActivityJoinRecord;
import com.youlu.campus.entity.data.HourActivityJoinRecord;
import com.youlu.campus.service.activity.ActivitySimulationDataService;
import com.youlu.campus.service.data.ActivityDataService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Objects;

@Slf4j
@Service
public class ActivityDataServiceImpl implements ActivityDataService {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Lazy
    @Autowired
    private ActivitySimulationDataService activitySimulationDataService;

    @Override
    public List<HourActivityJoinRecord> getHourDatas(ActivityDataQueryVO req) {
        log.info(":>>> 开始获取活动小时统计数据:{}", JSON.toJSON(req));
        Query query = new Query().addCriteria(Criteria.where("activityId").is(req.getActivityId()));
        if (Objects.isNull(req) || StringUtils.isBlank(req.getActivityId()) || Objects.isNull(req.getStartTime()) || Objects.isNull(req.getEndTime())) {
            log.error(":>>> 查询小时活动报名数据参数错误:活动ID、开始时间、结束时间为空");
            throw new BusinessException("查询小时活动报名数据参数错误:活动ID、开始时间、结束时间为空");
        }
        if (req.getStartTime() != null || req.getEndTime() != null) {
            Criteria criteria = Criteria.where("time");
            if (req.getStartTime() != null) {
                criteria.gte(TimeUtils.dateToISODate(req.getStartTime()));
            }
            if (req.getEndTime() != null) {
                criteria.lte(TimeUtils.dateToISODate(req.getEndTime()));
            }
            query.addCriteria(criteria);
        }
        query.with(Sort.by(Sort.Direction.ASC, "time"));
        List<HourActivityJoinRecord> records = mongoTemplate.find(query, HourActivityJoinRecord.class);
        ActivitySimulationData sData = activitySimulationDataService.findByActivityId(req.getActivityId());
        if (Objects.nonNull(sData)) {
            for (HourActivityJoinRecord data : records) {
                if (Objects.nonNull(data.getNum()) && Objects.nonNull(sData.getCoefficient())) {
                    Double dd = data.getNum() * sData.getCoefficient();
                    data.setNum(dd.intValue());
                }
            }
        }
        return records;
    }

    @Override
    public List<DayActivityJoinRecord> getDayDatas(ActivityDataQueryVO req) {
        log.info(":>>> 开始获取活动天统计数据:{}", JSON.toJSON(req));

        if (Objects.isNull(req) || StringUtils.isBlank(req.getActivityId()) || Objects.isNull(req.getStartTime()) || Objects.isNull(req.getEndTime())) {
            log.error(":>>> 获取小时活动数据参数错误:活动ID、时间纬度不能为空");
            throw new BusinessException("创建小时活动数据参数错误:活动ID、时间纬度不能为空");
        }
        Query query = new Query().addCriteria(Criteria.where("activityId").is(req.getActivityId()));
        if (req.getStartTime() != null || req.getEndTime() != null) {
            Criteria criteria = Criteria.where("time");
            if (req.getStartTime() != null) {
                criteria.gte(TimeUtils.dateToISODate(req.getStartTime()));
            }
            if (req.getEndTime() != null) {
                criteria.lte(TimeUtils.dateToISODate(new Date(req.getEndTime().getTime() + 24 * 3600 * 1000)));
            }
            query.addCriteria(criteria);
        }
        List<DayActivityJoinRecord> records = mongoTemplate.find(query, DayActivityJoinRecord.class);
        ActivitySimulationData sData = activitySimulationDataService.findByActivityId(req.getActivityId());
        if (Objects.nonNull(sData)) {
            for (DayActivityJoinRecord data : records) {
                if (Objects.nonNull(data.getNum()) && Objects.nonNull(sData.getCoefficient())) {
                    Double dd = data.getNum() * sData.getCoefficient();
                    data.setNum(dd.intValue());
                }

            }
        }
        return records;
    }

    @Override
    public void createHourActivityJoinRecord(HourActivityJoinRecord record) {
        log.info(":>>> 开始创建小时活动数据:{}", JSON.toJSONString(record));
        if (Objects.isNull(record) || StringUtils.isBlank(record.getActivityId()) || Objects.isNull(record.getNum()) || Objects.isNull(record.getTime())) {
            log.error(":>>> 创建小时活动数据参数错误:活动ID、数量、时间纬度不能为空");
            throw new BusinessException("创建小时活动数据参数错误:活动ID、数量、时间纬度不能为空");
        }
        try {
            Date date = new Date();
            Query query = new Query().addCriteria(Criteria.where("activityId").is(record.getActivityId()));
            Date startTime = TimeUtils.getEndOfHour(date);
            query.addCriteria(Criteria.where("time").is(startTime));
            HourActivityJoinRecord re = mongoTemplate.findOne(query, HourActivityJoinRecord.class);
            if (Objects.isNull(re)) {
                re = new HourActivityJoinRecord();
                re.setActivityId(record.getActivityId());
                re.setId(null);
                re.setTime(startTime);
                re.setCreatedTime(date);
                re.setNum(record.getNum());
                mongoTemplate.insert(re);
                log.info(":>>> 活动:{},消息报名人数不存在,新增", record.getActivityId());
                return;
            }
            Query queryUpdate = new Query().addCriteria(Criteria.where("id").is(re.getId()));
            Update update = new Update();
            update.set("updatedTime", date);
            update.inc("num", record.getNum());
            UpdateResult updateResult = mongoTemplate.updateFirst(queryUpdate, update, HourActivityJoinRecord.class);
            log.info(":>>> 活动:{},小时报名人数:{},更新结果:{}", record.getActivityId(), re.getNum() + record.getNum(), updateResult.getModifiedCount() > 0 ? true : false);
        } catch (Exception e) {
            log.error(":>>> 获取小时报名数据错误:{}", e);
        }

    }

    @Override
    public void createDayActivityJoinRecord(DayActivityJoinRecord record) {
        if (Objects.isNull(record) || StringUtils.isBlank(record.getActivityId()) || Objects.isNull(record.getNum()) || Objects.isNull(record.getTime())) {
            log.error(":>>> 创建天活动数据参数错误:活动ID、数量、时间纬度不能为空");
            throw new BusinessException("创建天活动数据参数错误:活动ID、数量、时间纬度不能为空");
        }
        try {
            Date date = new Date();
            Query query = new Query().addCriteria(Criteria.where("activityId").is(record.getActivityId()));
            Date startTime = TimeUtils.getDayStartTime(date);
            query.addCriteria(Criteria.where("time").is(startTime));
            DayActivityJoinRecord re = mongoTemplate.findOne(query, DayActivityJoinRecord.class);
            if (Objects.isNull(re)) {
                re = new DayActivityJoinRecord();
                re.setActivityId(record.getActivityId());
                re.setId(null);
                re.setTime(startTime);
                re.setCreatedTime(date);
                re.setNum(record.getNum());
                mongoTemplate.insert(re);
                log.info(":>>> 活动:{},消息日报名人数不存在,新增", record.getActivityId());
                return;
            }
            Query queryUpdate = new Query().addCriteria(Criteria.where("id").is(re.getId()));
            Update update = new Update();
            update.set("updatedTime", date);
            update.inc("num", record.getNum());
            UpdateResult updateResult = mongoTemplate.updateFirst(queryUpdate, update, DayActivityJoinRecord.class);
            log.info(":>>> 活动:{},天报名人数:{},更新结果为:{}", record.getActivityId(), re.getNum() + record.getNum(), updateResult.getModifiedCount() > 0 ? true : false);

        } catch (Exception e) {
            log.error(":>>> 获取天报名数据错误:{}", e);
        }

    }
}
